home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / Tools & Goodies / IntlTest / Sources / Commands.cpp < prev    next >
Encoding:
Text File  |  1996-04-23  |  16.5 KB  |  519 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Commands.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "IntlTest.hpp"
  11.  
  12. #ifndef COMMANDS_H
  13. #include "Commands.h"
  14. #endif
  15.  
  16. #ifndef PART_H
  17. #include "Part.h"
  18. #endif
  19.  
  20. #ifndef FRAME_H
  21. #include "Frame.h"
  22. #endif
  23.  
  24. #ifndef CONTENT_H
  25. #include "Content.h"
  26. #endif
  27.  
  28. #ifndef EDITVIEWS_H
  29. #include "EditViews.h"
  30. #endif
  31.  
  32. #ifndef SELECT_H
  33. #include "Select.h"
  34. #endif
  35.  
  36. // ----- Framework Includes -----
  37.  
  38. #ifndef FWPRESEN_H
  39. #include "FWPresen.h"
  40. #endif
  41.  
  42. // ----- OpenDoc Includes -----
  43.  
  44. #ifndef SOM_Module_OpenDoc_Commands_defined
  45. #include <CmdDefs.xh>
  46. #endif
  47.  
  48. //========================================================================================
  49. // RunTime Info
  50. //========================================================================================
  51.  
  52. #ifdef FW_BUILD_MAC
  53. #pragma segment odfIntlTest
  54. #endif
  55.  
  56. //========================================================================================
  57. // CIntlTestDropCommand
  58. //========================================================================================
  59.  
  60. FW_DEFINE_AUTO(CIntlTestDropCommand)
  61.  
  62. //----------------------------------------------------------------------------------------
  63. //    CIntlTestDropCommand constructor
  64. //----------------------------------------------------------------------------------------
  65.  
  66. CIntlTestDropCommand::CIntlTestDropCommand(Environment* ev,
  67.                                     FW_CFrame* frame,
  68.                                     FW_CEditView* dropView,
  69.                                     CIntlTestSelection* selection,
  70.                                     ODDragItemIterator* dropInfo, 
  71.                                     ODFacet* odFacet,
  72.                                     const FW_CPoint& dropPoint) : 
  73.     FW_CDropCommand(ev, frame, dropInfo, odFacet, dropPoint, FW_kCanUndo),
  74.     fDropEditView(dropView),
  75.     fTextSelection(selection),
  76.     fSavedOffset(0)
  77. {
  78.     // Ensure that dropped text is Internalized into the drop view
  79.     selection->SetContentEditView(dropView);
  80.  
  81.     SetMenuStringsFromResource(ev, kIntlTestUndoStrings, kUndoDropTextMsg, kRedoDropTextMsg);
  82.     FW_END_CONSTRUCTOR
  83. }
  84.  
  85. //----------------------------------------------------------------------------------------
  86. //    CIntlTestDropCommand destructor
  87. //----------------------------------------------------------------------------------------
  88.  
  89. CIntlTestDropCommand::~CIntlTestDropCommand()
  90. {
  91. }
  92.  
  93. //----------------------------------------------------------------------------------------
  94. //    CIntlTestDropCommand::SaveUndoState
  95. //----------------------------------------------------------------------------------------
  96.  
  97. void CIntlTestDropCommand::SaveUndoState(Environment* ev)
  98. {
  99.     short endOffset;
  100.     fSavedText = fDropEditView->GetSelectedText(ev);
  101.     fDropEditView->GetSelectionRange(ev, fSavedOffset, endOffset);
  102. }
  103.  
  104. //----------------------------------------------------------------------------------------
  105. //    CIntlTestDropCommand::SaveRedoState
  106. //----------------------------------------------------------------------------------------
  107. void CIntlTestDropCommand::SaveRedoState(Environment* ev)
  108. {
  109.     fDroppedText = fTextSelection->GetSelectedTestContent()->GetInternalizedText();
  110. }
  111.  
  112. //----------------------------------------------------------------------------------------
  113. //    CIntlTestDropCommand::UndoIt
  114. //----------------------------------------------------------------------------------------
  115.  
  116. void CIntlTestDropCommand::UndoIt(Environment* ev)
  117. {
  118.     this->SwapText(ev, fDroppedText.GetByteLength(), fSavedText);
  119. }
  120.  
  121. //----------------------------------------------------------------------------------------
  122. //    CIntlTestDropCommand::RedoIt
  123. //----------------------------------------------------------------------------------------
  124.  
  125. void CIntlTestDropCommand::RedoIt(Environment* ev)
  126. {
  127.     this->SwapText(ev, fSavedText.GetByteLength(), fDroppedText);
  128. }
  129.  
  130. //----------------------------------------------------------------------------------------
  131. //    CIntlTestDropCommand::SwapText
  132. //----------------------------------------------------------------------------------------
  133.  
  134. void CIntlTestDropCommand::SwapText(Environment* ev, FW_ByteCount bytesToRemove,
  135.                                     const FW_CString& textToRestore)
  136. {
  137.     // Remove designated text
  138.     fDropEditView->SelectText(ev, fSavedOffset, fSavedOffset+(short)bytesToRemove);
  139.     fDropEditView->DoTECommand(ev, kODCommandClear, true);
  140.  
  141.     // Restore the text
  142.     fDropEditView->InsertText(ev, textToRestore, fSavedOffset);
  143.  
  144.     // Perform notification
  145.     fDropEditView->Notify(ev, CEditNotification(fDropEditView));
  146. }
  147.  
  148. //========================================================================================
  149. //    class CIntlTestEditCommand
  150. //========================================================================================
  151.  
  152. FW_DEFINE_AUTO(CIntlTestEditCommand)
  153.  
  154. //----------------------------------------------------------------------------------------
  155. //    CIntlTestEditCommand constructor
  156. //----------------------------------------------------------------------------------------
  157. CIntlTestEditCommand::CIntlTestEditCommand(Environment* ev, 
  158.                             ODCommandID commandID,
  159.                             FW_CFrame* frame,
  160.                             CIntlTestSelection* selection,
  161.                             FW_CEditView* editView,
  162.                             FW_Boolean canUndo)
  163. :    FW_CClipboardCommand(ev, commandID, frame, canUndo),
  164.     fTextSelection(selection),
  165.     fEditView(editView),
  166.     fStartOffset(0),
  167.     fEndOffset(0)
  168. {
  169.     if (editView)
  170.         fTextSelection->SetContentEditView(editView);
  171. }
  172.  
  173. //----------------------------------------------------------------------------------------
  174. //    CIntlTestEditCommand destructor
  175. //----------------------------------------------------------------------------------------
  176. CIntlTestEditCommand::~CIntlTestEditCommand()
  177. {
  178. }
  179.  
  180. //----------------------------------------------------------------------------------------
  181. //    CIntlTestEditCommand::PreCommand
  182. //----------------------------------------------------------------------------------------
  183. void CIntlTestEditCommand::PreCommand(Environment* ev)
  184. {
  185.     ODCommandID id = GetCommandID(ev);
  186.     if ((id == kODCommandCopy) || (id == kODCommandCut))
  187.         fEditView->DoTECommand(ev, kODCommandCopy, true);    // Tell TE to copy the text
  188. }
  189.  
  190. //----------------------------------------------------------------------------------------
  191. //    CIntlTestEditCommand::CommandDone
  192. //----------------------------------------------------------------------------------------
  193. void CIntlTestEditCommand::CommandDone(Environment* ev)
  194. {
  195.     switch (GetCommandID(ev))
  196.     {
  197.         case kODCommandCut:
  198.         case kODCommandPaste:
  199.         case kODCommandClear:
  200.             fEditView->Notify(ev, CEditNotification(fEditView));
  201.     }
  202. }
  203.  
  204. //----------------------------------------------------------------------------------------
  205. //    CIntlTestEditCommand::SaveUndoState
  206. //----------------------------------------------------------------------------------------
  207. void CIntlTestEditCommand::SaveUndoState(Environment* ev)
  208. {
  209.     switch (GetCommandID(ev))
  210.     {
  211.         case kODCommandCut:
  212.         case kODCommandClear:
  213.             fPastedText = fEditView->GetSelectedText(ev);
  214.             fEditView->GetSelectionRange(ev, fStartOffset, fEndOffset);
  215.             break;
  216.  
  217.         case kODCommandPaste:
  218.             fSavedText = fEditView->GetSelectedText(ev);
  219.             fEditView->GetSelectionRange(ev, fStartOffset, fEndOffset);
  220.             break;
  221.     }
  222. }
  223.  
  224. //----------------------------------------------------------------------------------------
  225. //    CIntlTestEditCommand::SaveRedoState
  226. //----------------------------------------------------------------------------------------
  227. void CIntlTestEditCommand::SaveRedoState(Environment* ev)
  228. {
  229.     if (GetCommandID(ev) == kODCommandPaste)
  230.     {
  231.         fPastedText = fTextSelection->GetSelectedTestContent()->GetInternalizedText();
  232.     }
  233. }
  234.  
  235. //----------------------------------------------------------------------------------------
  236. //    CIntlTestEditCommand::UndoIt
  237. //----------------------------------------------------------------------------------------
  238. void CIntlTestEditCommand::UndoIt(Environment* ev)
  239. {
  240.     FW_CClipboardCommand::UndoIt(ev);    // call inherited
  241.  
  242.     switch (GetCommandID(ev))
  243.     {
  244.         case kODCommandCut:
  245.         case kODCommandClear:
  246.             this->RestoreText(ev);
  247.             break;
  248.  
  249.         case kODCommandPaste:
  250.             this->RemoveAndRestoreText(ev, fPastedText.GetByteLength(), fSavedText);
  251.             break;
  252.     }    
  253. }
  254.  
  255. //----------------------------------------------------------------------------------------
  256. //    CIntlTestEditCommand::RedoIt
  257. //----------------------------------------------------------------------------------------
  258. void CIntlTestEditCommand::RedoIt(Environment* ev)
  259. {
  260.     FW_CClipboardCommand::RedoIt(ev);    // call inherited
  261.  
  262.     switch (GetCommandID(ev))
  263.     {
  264.         case kODCommandCut:
  265.         case kODCommandClear:
  266.             this->RemoveText(ev);
  267.             break;
  268.  
  269.         case kODCommandPaste:
  270.             this->RemoveAndRestoreText(ev, fSavedText.GetByteLength(), fPastedText);
  271.             break;
  272.     }    
  273. }
  274.  
  275. //----------------------------------------------------------------------------------------
  276. //    CIntlTestEditCommand::RemoveText
  277. //----------------------------------------------------------------------------------------
  278. void CIntlTestEditCommand::RemoveText(Environment* ev)
  279. {
  280.     fEditView->SelectText(ev, fStartOffset, fEndOffset);
  281.     fEditView->DoTECommand(ev, kODCommandClear, true);
  282.     fEditView->Notify(ev, CEditNotification(fEditView));
  283. }
  284.  
  285. //----------------------------------------------------------------------------------------
  286. //    CIntlTestEditCommand::RestoreText
  287. //----------------------------------------------------------------------------------------
  288. void CIntlTestEditCommand::RestoreText(Environment* ev)
  289. {
  290.     // Insert the saved text back into the EditView
  291.     fEditView->InsertText(ev, fPastedText, fStartOffset);
  292.     fEditView->Notify(ev, CEditNotification(fEditView));
  293. }
  294.  
  295. //----------------------------------------------------------------------------------------
  296. //    CIntlTestEditCommand::RemoveAndRestoreText
  297. //----------------------------------------------------------------------------------------
  298. void CIntlTestEditCommand::RemoveAndRestoreText(Environment* ev, FW_ByteCount bytesToRemove,
  299.                                                 const FW_CString& textToRestore)
  300. {
  301.     // Remove designated text
  302.     fEditView->SelectText(ev, fStartOffset, fStartOffset+(short)bytesToRemove);
  303.     fEditView->DoTECommand(ev, kODCommandClear, true);
  304.  
  305.     // Restore the text
  306.     fEditView->InsertText(ev, textToRestore, fStartOffset);
  307.  
  308.     // Finally, perform notification
  309.     fEditView->Notify(ev, CEditNotification(fEditView));
  310. }
  311.  
  312. //========================================================================================
  313. // CTypingCommand
  314. //========================================================================================
  315.  
  316. FW_DEFINE_AUTO(CTypingCommand)
  317.  
  318. //-----------------------------------------------------------------------------------------
  319. CTypingCommand::CTypingCommand(Environment* ev, 
  320.                                ODCommandID commandID,
  321.                                FW_CFrame* frame, 
  322.                                FW_CEditView* editView,
  323.                                FW_Boolean canUndo,
  324.                                char firstChar)
  325. :    FW_CCommand(ev, commandID, frame, canUndo),
  326.     fEditView(editView),
  327.     fCompleted(false),
  328.     fFirstChar(firstChar),
  329.     fTypedText(""),
  330.     fSavedText(""),
  331.     fStartOffset(0),
  332.     fEndOffset(0)
  333. {
  334.     SetMenuStrings(ev, "Undo Typing", "Redo Typing");
  335.     FW_END_CONSTRUCTOR
  336. }
  337.  
  338. //-----------------------------------------------------------------------------------------
  339. CTypingCommand::~CTypingCommand()
  340. {
  341. }
  342.  
  343. //-----------------------------------------------------------------------------------------
  344. void CTypingCommand::AddCharacter(Environment* ev, char ch)
  345. {
  346.     if (ch == chBackspace)
  347.         Backspace(ev, ch);
  348.     else
  349.         fTypedText.Append(ch);
  350. }
  351.  
  352. //-----------------------------------------------------------------------------------------
  353. void CTypingCommand::Backspace(Environment* ev, char bsChar)
  354. {
  355.     short startOffset, endOffset;
  356.     fEditView->GetSelectionRange(ev, startOffset, endOffset);
  357.  
  358.     if ((startOffset == 0) && (endOffset == 0)) return;    // nothing to backspace over
  359.  
  360.     //--- Are we deleting a selection?
  361.     if (endOffset != startOffset)            // some text is selected
  362.     {
  363.         fTypedText = "";                    // replace selection w/empty string
  364.     }
  365.     else if (startOffset <= fStartOffset)    // Backspacing past the start of typing
  366.     {
  367.         // save the character we're about to backspace over
  368.         FW_PlatformHandle teh = fEditView->GetPlatformEditHandle(ev);
  369.         TERec* tep = (TERec*) *teh;
  370.         char* p = (char*) (*(tep->hText)) + startOffset - 1;
  371.         fSavedText.Insert(p, 1, 0);
  372.         fStartOffset--;
  373.     }
  374.     else                                    // backspace over typed text
  375.     {
  376.         FW_ByteCount count = fTypedText.GetByteLength();
  377.         fTypedText.Truncate(count-1);        // cut off the last character of the saved text
  378.     }
  379. }
  380.  
  381. //-----------------------------------------------------------------------------------------
  382. void CTypingCommand::CompleteTyping(Environment* ev)
  383. {
  384.     if (fCompleted) return;
  385.  
  386.     if (!fTypedText.IsEmpty())
  387.     {
  388.         if (GetCanUndo(ev))
  389.             this->SaveRedoState(ev);        // save new state, for later Redo
  390.     
  391.         fCompleted = true;
  392.     }
  393. }
  394.  
  395. //-----------------------------------------------------------------------------------------
  396. void CTypingCommand::DoIt(Environment* ev)
  397. {
  398.     if (GetCanUndo(ev))
  399.         this->SaveUndoState(ev);        // save current state, for later Undo
  400.  
  401.     AddCharacter(ev, fFirstChar);
  402. }
  403.  
  404. //-----------------------------------------------------------------------------------------
  405. void CTypingCommand::SaveUndoState(Environment* ev)
  406. {
  407.     // Get current selection info, for Undo
  408.     fSavedText = fEditView->GetSelectedText(ev);
  409.     fEditView->GetSelectionRange(ev, fStartOffset, fEndOffset);
  410. }
  411.  
  412. //-----------------------------------------------------------------------------------------
  413. void CTypingCommand::SaveRedoState(Environment* ev)
  414. {
  415.     // fTypedText contains the new text - what else do we need?
  416. }
  417.  
  418. //-----------------------------------------------------------------------------------------
  419. void CTypingCommand::UndoIt(Environment* ev)
  420. {
  421.     this->CompleteTyping(ev);
  422.  
  423.     fEditView->SelectText(ev, fStartOffset, fStartOffset+fTypedText.GetByteLength());
  424.     fEditView->SetSelectedText(ev, fSavedText);
  425. }
  426.  
  427. //-----------------------------------------------------------------------------------------
  428. void CTypingCommand::RedoIt(Environment* ev)
  429. {
  430.     fEditView->SelectText(ev, fStartOffset, fStartOffset+fSavedText.GetByteLength());
  431.     fEditView->SetSelectedText(ev, fTypedText);
  432. }
  433.  
  434. //========================================================================================
  435. //    class CTSMTypingCommand
  436. //========================================================================================
  437.  
  438. FW_DEFINE_AUTO(CTSMTypingCommand)
  439.  
  440. //-----------------------------------------------------------------------------------------
  441. CTSMTypingCommand::CTSMTypingCommand(Environment* ev, 
  442.                                      ODCommandID commandID,
  443.                                      FW_CFrame* frame, 
  444.                                      FW_CEditView* editView,
  445.                                      CTSMInput* firstInput)
  446. :    CTypingCommand(ev, commandID, frame, editView, FW_kCanUndo, 0),
  447.     fFirstInput(firstInput)
  448. {
  449. }
  450.  
  451. //-----------------------------------------------------------------------------------------
  452. CTSMTypingCommand::~CTSMTypingCommand()
  453. {
  454. }
  455.  
  456. //-----------------------------------------------------------------------------------------
  457. void CTSMTypingCommand::AddInput(Environment* ev, CTSMInput* input)
  458. {
  459.     if (input->IsMultiByte())
  460.         fTypedText.Append(input->fChars, input->fByteCount);
  461.     else if (input->fByte == chBackspace)
  462.         Backspace(ev);
  463.     else
  464.         fTypedText.Append(input->fByte);
  465. }
  466.  
  467. //-----------------------------------------------------------------------------------------
  468. void CTSMTypingCommand::Backspace(Environment* ev)
  469. {
  470.     short bytesPerChar = 2;
  471.     short startOffset, endOffset;
  472.     fEditView->GetSelectionRange(ev, startOffset, endOffset);
  473.  
  474.     if ((startOffset == 0) && (endOffset == 0)) return;    // nothing to backspace over
  475.  
  476.     //--- Are we deleting a selection?
  477.     if (endOffset != startOffset)            // some text is selected
  478.     {
  479.         fTypedText = "";                    // replace selection w/empty string
  480.     }
  481.     else if (startOffset <= fStartOffset)    // Backspacing past the start of typing
  482.     {
  483.         // save the character we're about to backspace over
  484.         FW_PlatformHandle teh = fEditView->GetPlatformEditHandle(ev);
  485.         TERec* tep = (TERec*) *teh;
  486.         char* p = (char*) (*(tep->hText)) + startOffset;
  487.         // Check if the previous character is a single-byte CR
  488.         --p;
  489.         if (*p == chReturn)
  490.             bytesPerChar = 1;
  491.         else
  492.             --p;
  493.         fSavedText.Insert(p, bytesPerChar, 0);
  494.         fStartOffset -= bytesPerChar;
  495.     }
  496.     else                                    // backspace over typed text
  497.     {
  498.         FW_ByteCount count = fTypedText.GetByteLength();
  499.         FW_ASSERT(count > 0);
  500.         // Check if the last typed character is a single-byte CR
  501.         if (fTypedText[count-1] == chReturn)        // FW_CString oper[] is 0-based
  502.             bytesPerChar = 1;
  503.         fTypedText.Truncate(count-bytesPerChar);    // cut off the last character of the saved text
  504.     }
  505. }
  506.  
  507. //-----------------------------------------------------------------------------------------
  508. void CTSMTypingCommand::DoIt(Environment* ev)
  509. {
  510.     if (GetCanUndo(ev))
  511.         this->SaveUndoState(ev);            // save current state, for later Undo
  512.  
  513.     if (fFirstInput)
  514.     {
  515.         AddInput(ev, fFirstInput);
  516.         fFirstInput = NULL;                    // only valid for this one time
  517.     }
  518. }
  519.